React ์ ์ง์ ํฅ์์ ๊ตฌํํ์ฌ JavaScript๊ฐ ๋นํ์ฑํ๋๊ฑฐ๋ ์ด๊ธฐ ๋ก๋ ์ค์๋ ์ ๊ทผ์ฑ, ์ฑ๋ฅ, ๊ฒฌ๊ณ ์ฑ์ด ๋ฐ์ด๋ ์น์ฌ์ดํธ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์.
React ์ ์ง์ ํฅ์: JavaScript ์ต์ ๋ ์ปดํฌ๋ํธ ๊ตฌ์ถํ๊ธฐ
์ค๋๋ ์ ์น ๊ฐ๋ฐ ํ๊ฒฝ์์ React์ ๊ฐ์ JavaScript ํ๋ ์์ํฌ๋ ์ด๋์๋ ์กด์ฌํฉ๋๋ค. ์ด๋ฌํ ํ๋ ์์ํฌ๋ ๋์ ์ด๊ณ ์ํธ์์ฉ์ ์ธ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋๋ ๊ฐ๋ ฅํ ๋๊ตฌ๋ฅผ ์ ๊ณตํ์ง๋ง, JavaScript์๋ง ์ ์ ์ผ๋ก ์์กดํ๋ฉด ์ ๊ทผ์ฑ, ์ฑ๋ฅ, SEO ๊ด๋ จ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ ์ ์ง์ ํฅ์(Progressive Enhancement, PE)์ด ๋ฑ์ฅํฉ๋๋ค. ์ ์ง์ ํฅ์์ ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฅ์ด๋ JavaScript ์ฌ์ฉ ๊ฐ๋ฅ ์ฌ๋ถ์ ๊ด๊ณ์์ด ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ํต์ฌ ์น์ฌ์ดํธ ๊ธฐ๋ฅ๊ณผ ์ฝํ ์ธ ๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ์ฐ์ ์ํ๋ ์น ๊ฐ๋ฐ ์ ๋ต์ ๋๋ค. React ์ ์ง์ ํฅ์์ JavaScript ์์ด๋ ์๋ํ๋ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ถํ๋ ๋ฐ ์ค์ ์ ๋์ด, ๊ธฐ๋ณธ ๊ฒฝํ์ ์ ๊ณตํ ํ JavaScript๋ฅผ ํตํด ๋ ํ๋ถํ ์ํธ์์ฉ์ผ๋ก ํฅ์์ํค๋ ๋ฐฉ์์ ๋๋ค.
์ ์ง์ ํฅ์์ด๋ ๋ฌด์์ธ๊ฐ?
์ ์ง์ ํฅ์์ ์๋ก์ด ๊ฐ๋ ์ด ์๋๋๋ค. ์ด๊ฒ์ HTML๊ณผ CSS์ ๊ฒฌ๊ณ ํ ๊ธฐ๋ฐ์์ ์์ํ์ฌ ์น์ฌ์ดํธ๋ฅผ ๊ณ์ธต์ ์ผ๋ก ๊ตฌ์ถํ๋ ๊ฒ์ ์นํธํ๋ ์ฒ ํ์ ๋๋ค. ์ด ๊ธฐ๋ฐ์ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์, ๋๋ฆฐ ์ธํฐ๋ท ์ฐ๊ฒฐ์ ์ฌ์ฉํ๋ ์ฌ์ฉ์, ๋๋ JavaScript๋ฅผ ๋นํ์ฑํํ ์ฌ์ฉ์๋ฅผ ํฌํจํ ๋ชจ๋ ์ฌ๋์ด ์ฝํ ์ธ ์ ์ ๊ทผํ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค. ๊ทธ ํ JavaScript๋ ๋ ํ๋ถํ๊ณ ์ํธ์์ฉ์ ์ธ ๊ฒฝํ์ ์ ๊ณตํ๊ธฐ ์ํ ํฅ์ ๊ธฐ๋ฅ์ผ๋ก ์ถ๊ฐ๋ฉ๋๋ค. ์ง์ ์ง๋ ๊ฒ์ ๋น์ ํ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ถํฐ ์์ํ ๋ค์ ํ๋ คํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
์ ์ง์ ํฅ์์ ํต์ฌ ์์น:
- ์ ๊ทผ์ฑ ์ฐ์ : ๋ณด์กฐ ๊ธฐ์ ์ ์ฌ์ฉํ๋ ์ฌ์ฉ์๋ฅผ ํฌํจํ ๋ชจ๋ ์ฌ์ฉ์๊ฐ ํต์ฌ ์ฝํ ์ธ ์ ๊ธฐ๋ฅ์ ์ ๊ทผํ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ์๋งจํฑ HTML: ์ฝํ ์ธ ์ ๊ตฌ์กฐ์ ์๋ฏธ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํด HTML ์์๋ฅผ ์ ์ ํ๊ฒ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ์ ๊ทผ์ฑ๊ณผ SEO์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ์ฐ์ํ ์ ํ(Graceful Degradation): JavaScript๊ฐ ์คํจํ๊ฑฐ๋ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ์๋ ์น์ฌ์ดํธ๋ ์ํธ์์ฉ ์์ค์ด ๊ฐ์ํ๋๋ผ๋ ์ฌ์ ํ ์ฌ์ฉ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค.
- ์ฑ๋ฅ ์ต์ ํ: ์ด๊ธฐ ํ์ด์ง ๋ก๋์ ํ์ํ JavaScript์ ์์ ์ต์ํํฉ๋๋ค.
React์์ ์ ์ง์ ํฅ์์ด ์ค์ํ ์ด์
React๋ ๊ธฐ๋ณธ์ ์ผ๋ก JavaScript์ ํฌ๊ฒ ์์กดํ๋ ํ๋ ์์ํฌ์ ๋๋ค. React ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ธ๋ผ์ฐ์ ์์ ๋ ๋๋ง๋ ๋, ์ผ๋ฐ์ ์ผ๋ก ์๋นํ ์์ JavaScript๋ฅผ ๋ค์ด๋ก๋ํ๊ณ , ํ์ฑํ๊ณ , ์คํํด์ผ ํฉ๋๋ค. ์ด๋ ์ฌ๋ฌ ๊ฐ์ง ๋ฌธ์ ๋ก ์ด์ด์ง ์ ์์ต๋๋ค:
- ๋๋ฆฐ ์ด๊ธฐ ๋ก๋ ์๊ฐ: ๋๋ฆฐ ์ฐ๊ฒฐ์ด๋ ์ฑ๋ฅ์ด ๋ฎ์ ๊ธฐ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ์ฌ์ฉ์๋ ์น์ฌ์ดํธ๊ฐ ์ํธ์์ฉ ๊ฐ๋ฅํด์ง๊ธฐ๊น์ง ์๋นํ ์ง์ฐ์ ๊ฒฝํํ ์ ์์ต๋๋ค.
- ์ ๊ทผ์ฑ ๋ฌธ์ : ๋ ๋๋ง์ JavaScript๊ฐ ํ์ํ ๊ฒฝ์ฐ ๋ณด์กฐ ๊ธฐ์ ์ ์์กดํ๋ ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๊ฐ ์ฝํ ์ธ ์ ์ ๊ทผํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช์ ์ ์์ต๋๋ค.
- SEO ๋ฌธ์ : ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๊ฐ JavaScript์ ํฌ๊ฒ ์์กดํ๋ ์ฝํ ์ธ ๋ฅผ ์ ๋๋ก ์ธ๋ฑ์ฑํ์ง ๋ชปํ ์ ์์ต๋๋ค.
React์ ์ ์ง์ ํฅ์์ ๊ตฌํํ๋ฉด JavaScript ์์ด๋ ๊ธฐ๋ฅํ๋ ๊ธฐ๋ณธ ๊ฒฝํ์ ์ ๊ณตํจ์ผ๋ก์จ ์ด๋ฌํ ๋ฌธ์ ๋ค์ ํด๊ฒฐํฉ๋๋ค. ์ด๋ ์ ๊ทผ์ฑ๊ณผ ์ฑ๋ฅ์ ํฅ์์ํฌ ๋ฟ๋ง ์๋๋ผ ๊ฒ์ ์์ง์ด ์ฝํ ์ธ ๋ฅผ ์ฝ๊ฒ ํฌ๋กค๋งํ๊ณ ์ธ๋ฑ์ฑํ ์ ์๋๋ก ํ์ฌ SEO๋ฅผ ๊ฐํํฉ๋๋ค.
React ์ ์ง์ ํฅ์์ ์ํ ๊ธฐ์
React์์ ์ ์ง์ ํฅ์์ ๊ตฌํํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๋ช ๊ฐ์ง ๊ธฐ์ ์ด ์์ต๋๋ค:
1. ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง (SSR)
์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)์ React ์ปดํฌ๋ํธ๋ฅผ ์๋ฒ์์ ๋ ๋๋งํ๊ณ ๊ทธ ๊ฒฐ๊ณผ์ธ HTML์ ํด๋ผ์ด์ธํธ๋ก ๋ณด๋ด๋ ๊ธฐ์ ์ ๋๋ค. ์ด๋ฅผ ํตํด ๋ธ๋ผ์ฐ์ ๋ JavaScript๊ฐ ๋ค์ด๋ก๋๋๊ณ ์คํ๋๊ธฐ ์ ์๋ ์ฝํ ์ธ ๋ฅผ ์ฆ์ ํ์ํ ์ ์์ต๋๋ค. SSR์ ์ฌ๋ฌ ๊ฐ์ง ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
- ์ด๊ธฐ ๋ก๋ ์๊ฐ ๊ฐ์ : ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฏธ๋ฆฌ ๋ ๋๋ง๋ HTML์ ์์ ํ์ฌ ์ด๊ธฐ ํ์ด์ง ๋ก๋ ์๋๊ฐ ๋นจ๋ผ์ง๋๋ค.
- ํฅ์๋ SEO: ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๊ฐ ๋ฏธ๋ฆฌ ๋ ๋๋ง๋ HTML์ ์ฝ๊ฒ ์ธ๋ฑ์ฑํ ์ ์์ต๋๋ค.
- ๋ ๋์ ์ ๊ทผ์ฑ: ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๋ JavaScript๊ฐ ๋ก๋๋๊ธฐ ์ ์๋ ์ฝํ ์ธ ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
Next.js๋ Remix์ ๊ฐ์ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ฉด React์์ SSR์ ๋น๊ต์ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค. ์ด๋ฌํ ํ๋ ์์ํฌ๋ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง, ๋ผ์ฐํ ๋ฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ๋ํ ๋ด์ฅ ์ง์์ ์ ๊ณตํฉ๋๋ค.
Next.js๋ฅผ ์ฌ์ฉํ ์์ :
Next.js๋ `pages` ๋๋ ํ ๋ฆฌ์ ํ์ด์ง์ ๋ํด ์๋์ผ๋ก SSR์ ์ฒ๋ฆฌํฉ๋๋ค. ๋ค์์ ๊ฐ๋จํ ์์ ์ ๋๋ค:
// pages/index.js
function HomePage() {
return ์ ์ ์น์ฌ์ดํธ์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค!
;
}
export default HomePage;
์ฌ์ฉ์๊ฐ ํํ์ด์ง๋ฅผ ๋ฐฉ๋ฌธํ๋ฉด Next.js๋ ์๋ฒ์์ `HomePage` ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๊ณ ๊ฒฐ๊ณผ HTML์ ๋ธ๋ผ์ฐ์ ๋ก ๋ณด๋ ๋๋ค.
2. ์ ์ ์ฌ์ดํธ ์์ฑ (SSG)
์ ์ ์ฌ์ดํธ ์์ฑ(SSG)์ ๋น๋ ์์ React ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๊ณ ๊ฒฐ๊ณผ HTML ํ์ผ์ ํด๋ผ์ด์ธํธ์ ์ง์ ์ ๊ณตํ๋ ๊ธฐ์ ์ ๋๋ค. ์ด๋ ๊ฐ ์์ฒญ์ ๋ํด ์๋ฒ ์ธก ์ฒ๋ฆฌ๊ฐ ํ์ ์์ด ๋ฏธ๋ฆฌ ์์ฑ๋ HTML์ด๊ธฐ ๋๋ฌธ์ SSR๋ณด๋ค ํจ์ฌ ๋น ๋ฆ ๋๋ค.
- ๊ทน๋๋ก ๋น ๋ฅธ ๋ก๋ ์๊ฐ: HTML ํ์ผ์ด CDN์์ ์ง์ ์ ๊ณต๋๋ฏ๋ก ๋ก๋ ์๊ฐ์ด ๋งค์ฐ ๋น ๋ฆ ๋๋ค.
- ํฅ์๋ ๋ณด์: ์๋ฒ ์ธก ์ฝ๋ ์คํ์ด ์์ด ๊ณต๊ฒฉ ํ๋ฉด์ด ์ค์ด๋ญ๋๋ค.
- ํ์ฅ์ฑ: ์น์ฌ์ดํธ๊ฐ ์ ์ ํ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ด ํ์ฅ์ด ์ฉ์ดํฉ๋๋ค.
Gatsby๋ Next.js์ ๊ฐ์ ํ๋ ์์ํฌ๋ SSG๋ฅผ ์ง์ํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋น๋ ์์ React ์ปดํฌ๋ํธ๋ก๋ถํฐ ์ ์ HTML ํ์ผ์ ์์ฑํ ์ ์์ต๋๋ค.
Next.js๋ฅผ ์ฌ์ฉํ ์์ :
Next.js์์ SSG๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด `getStaticProps` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ด๋ฅผ ์ปดํฌ๋ํธ์ props๋ก ์ ๋ฌํ ์ ์์ต๋๋ค.
// pages/blog/[id].js
export async function getStaticProps({ params }) {
const postId = params.id;
// API๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฒ์๋ฌผ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค
const post = { id: postId, title: `๊ฒ์๋ฌผ ${postId}`, content: `๊ฒ์๋ฌผ ${postId}์ ๋ด์ฉ์
๋๋ค` };
return {
props: {
post,
},
};
}
export async function getStaticPaths() {
// `id` ๋งค๊ฐ๋ณ์์ ๋ํ ๊ฐ๋ฅํ ๊ฐ๋ค์ ์ ์ํฉ๋๋ค
const paths = [
{ params: { id: '1' } },
{ params: { id: '2' } },
{ params: { id: '3' } },
];
return {
paths,
fallback: false, // ํ์์ ๋ฐ๋ผ ํ์ด์ง๋ฅผ ์์ฑํ๋ ค๋ฉด true๋ก ์ค์
};
}
function BlogPost({ post }) {
return (
{post.title}
{post.content}
);
}
export default BlogPost;
Next.js๋ ๋น๋ ์์ ๊ฐ ๊ฒ์๋ฌผ์ ๋ํ ์ ์ HTML ํ์ผ์ ์์ฑํฉ๋๋ค.
3. `
`
์ด ์ฝํ
์ธ ๋ JavaScript๊ฐ ํ์ฑํ๋ ๊ฒฝ์ฐ ํ์๋ฉ๋๋ค.
`
4. ์กฐ๊ฑด๋ถ ๋ ๋๋ง
์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ฌ์ฉํ๋ฉด JavaScript ํ์ฑํ ์ฌ๋ถ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ ์ฝํ ์ธ ๋ฅผ ๋ ๋๋งํ ์ ์์ต๋๋ค. ์ด๋ฅผ ์ฌ์ฉํ์ฌ JavaScript ์์ด ๊ธฐ๋ณธ ๊ฒฝํ์ ์ ๊ณตํ๋ฉด์ JavaScript ๊ธฐ๋ฅ์ผ๋ก ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ์ ์ง์ ์ผ๋ก ํฅ์์ํฌ ์ ์์ต๋๋ค.
import { useState, useEffect } from 'react';
function MyComponent() {
const [isJavaScriptEnabled, setIsJavaScriptEnabled] = useState(true);
useEffect(() => {
// JavaScript๊ฐ ํ์ฑํ๋์๋์ง ํ์ธํฉ๋๋ค. ์ด๊ฒ์ ๋จ์ํ๋ ์์ ์
๋๋ค.
// ์ค์ ์๋๋ฆฌ์ค์์๋ ๋ ๊ฒฌ๊ณ ํ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ผ ํ ์ ์์ต๋๋ค.
setIsJavaScriptEnabled(typeof window !== 'undefined');
}, []);
return (
{isJavaScriptEnabled ? (
์ด ์ฝํ
์ธ ๋ JavaScript๋ก ๋ ๋๋ง๋์์ต๋๋ค.
) : (
์ด ์ฝํ
์ธ ๋ JavaScript ์์ด ๋ ๋๋ง๋์์ต๋๋ค.
)}
);
}
export default MyComponent;
์ด ์์ ๋ `useState`์ `useEffect` ํ ์ ์ฌ์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ์์ JavaScript๊ฐ ํ์ฑํ๋์๋์ง ํ์ธํฉ๋๋ค. ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค๋ฅธ ์ฝํ ์ธ ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
5. ์๋งจํฑ HTML ์ฌ์ฉ
์๋งจํฑ HTML ์์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ ๊ทผ์ฑ๊ณผ ์ ์ง์ ํฅ์ ๋ชจ๋์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์๋งจํฑ HTML ์์๋ ์ฝํ
์ธ ์ ์๋ฏธ์ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํ์ฌ ๋ณด์กฐ ๊ธฐ์ ๊ณผ ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๊ฐ ๋ ์ฝ๊ฒ ์ดํดํ ์ ์๋๋ก ๋ง๋ญ๋๋ค. ์๋ฅผ ๋ค์ด, `
๊ธฐ์ฌ ์ ๋ชฉ
๊ธฐ์ฌ ๋ด์ฉ์ด ์ฌ๊ธฐ์ ๋ค์ด๊ฐ๋๋ค...
6. JavaScript์ ์ ์ง์ ๋ก๋ฉ
๋ชจ๋ JavaScript๋ฅผ ํ ๋ฒ์ ๋ก๋ํ๋ ๋์ , ํ์์ ๋ฐ๋ผ ์ ์ง์ ์ผ๋ก ๋ก๋ํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค. ์ด๋ ์ด๊ธฐ ํ์ด์ง ๋ก๋ ์๊ฐ์ ํฌ๊ฒ ๊ฐ์ ํ ์ ์์ต๋๋ค. ์ฝ๋ ๋ถํ ๋ฐ ์ง์ฐ ๋ก๋ฉ๊ณผ ๊ฐ์ ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ํ์ํ ๊ฒฝ์ฐ์๋ง JavaScript๋ฅผ ๋ก๋ํ ์ ์์ต๋๋ค.
์ฝ๋ ๋ถํ :
์ฝ๋ ๋ถํ ์ ์ฌ์ฉํ๋ฉด JavaScript ์ฝ๋๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ๋ก๋ํ ์ ์๋ ๋ ์์ ์ฒญํฌ๋ก ๋๋ ์ ์์ต๋๋ค. ์ด๋ ์ด๊ธฐ ๋ฒ๋ค ํฌ๊ธฐ๋ฅผ ์ค์ด๊ณ ์ด๊ธฐ ๋ก๋ ์๊ฐ์ ๊ฐ์ ํฉ๋๋ค.
์ง์ฐ ๋ก๋ฉ:
์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ๋ฉด ์ปดํฌ๋ํธ๋ ๋ชจ๋์ด ํ์ํ ๋๋ง ๋ก๋ํ ์ ์์ต๋๋ค. ์ด๋ ํญ์ด๋ ์์ฝ๋์ธ์ ์ปดํฌ๋ํธ์ ๊ฐ์ด ํ์ด์ง์ ์ฒ์์๋ ๋ณด์ด์ง ์๋ ์ปดํฌ๋ํธ์ ์ ์ฉํ ์ ์์ต๋๋ค.
7. ๊ธฐ๋ณธ ์ํธ์์ฉ์ ์ํ CSS ํ์ฉ
๋ชจ๋ ์ํธ์์ฉ ์์์ JavaScript๋ฅผ ์์กดํ๊ธฐ ์ ์ CSS๋ก ๋ฌด์์ ๋ฌ์ฑํ ์ ์๋์ง ํ์ํด ๋ณด์ญ์์ค. ํธ๋ฒ ํจ๊ณผ, ํฌ์ปค์ค ์ํ, ๊ธฐ๋ณธ ์์ ์ ํจ์ฑ ๊ฒ์ฌ์ ๊ฐ์ ๊ฐ๋จํ ์ํธ์์ฉ์ CSS๋ก ์ฒ๋ฆฌํ์ฌ JavaScript์ ๋ํ ์์กด๋๋ฅผ ์ค์ผ ์ ์์ต๋๋ค. `:hover`, `:focus`, `:active`์ ๊ฐ์ CSS ๊ฐ์ ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ JavaScript ์์ด ์ํธ์์ฉ ์์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
.my-button { background-color: #4CAF50; color: white; padding: 10px 20px; border: none; cursor: pointer; } .my-button:hover { background-color: #3e8e41; }
React ์ ์ง์ ํฅ์์ ์ค์ ์์
React์์ ์ ์ง์ ํฅ์์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ช ๊ฐ์ง ์ค์ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
์์ 1: ๊ฐ๋จํ ๋ฌธ์ ์์
๋ฌธ์ ์์์ ๋ง์ ์น์ฌ์ดํธ์์ ํํ ๋ณผ ์ ์๋ ์์์ ๋๋ค. ์ ์ง์ ํฅ์์ ์ฌ์ฉํ์ฌ ๋ฌธ์ ์์์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- HTML ์์: ํ์ํ ์ ๋ ฅ ํ๋์ ์ ์ถ ๋ฒํผ์ด ์๋ ๊ธฐ๋ณธ HTML ์์์ผ๋ก ์์ํฉ๋๋ค. ์์์ `action`๊ณผ `method` ์์ฑ์ด ์๋์ง ํ์ธํฉ๋๋ค.
- ์๋ฒ ์ธก ์ฒ๋ฆฌ: ์์ ์ ์ถ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์๋ฒ ์ธก ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด JavaScript ์์ด๋ ์์์ ์ ์ถํ ์ ์์ต๋๋ค.
- JavaScript ํฅ์: ํด๋ผ์ด์ธํธ ์ธก ์ ํจ์ฑ ๊ฒ์ฌ, AJAX ์ ์ถ, ์ค์๊ฐ ํผ๋๋ฐฑ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ผ๋ก ์์์ ํฅ์์ํค๊ธฐ ์ํด JavaScript๋ฅผ ์ถ๊ฐํฉ๋๋ค.
HTML (๊ธฐ๋ณธ ์์):
React (JavaScript ํฅ์):
import React, { useState } from 'react';
function ContactForm() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [message, setMessage] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false);
const [submissionStatus, setSubmissionStatus] = useState(null);
const handleSubmit = async (e) => {
e.preventDefault();
setIsSubmitting(true);
try {
const response = await fetch('/submit-form', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, email, message }),
});
if (response.ok) {
setSubmissionStatus('success');
setName('');
setEmail('');
setMessage('');
} else {
setSubmissionStatus('error');
}
} catch (error) {
setSubmissionStatus('error');
} finally {
setIsSubmitting(false);
}
};
return (
);
}
export default ContactForm;
์์ 2: ๋ด๋น๊ฒ์ด์ ๋ฉ๋ด
๋ด๋น๊ฒ์ด์ ๋ฉ๋ด๋ ์ ์ง์ ํฅ์์ผ๋ก ๊ฐ์ ํ ์ ์๋ ๋ ๋ค๋ฅธ ์ผ๋ฐ์ ์ธ ์์์ ๋๋ค.
- HTML ๋ฉ๋ด: ๋งํฌ(`
- `)๊ฐ ์๋ ๊ธฐ๋ณธ HTML ๋น์์ ๋ชฉ๋ก(`
- `)์ผ๋ก ์์ํฉ๋๋ค. ์ด๋ JavaScript ์์ด๋ ์๋ํ๋ ๊ธฐ๋ณธ ๋ฉ๋ด ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- CSS ์คํ์ผ๋ง: CSS๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ๋ด ์คํ์ผ์ ์ง์ ํ๊ณ ์๊ฐ์ ์ผ๋ก ๋งค๋ ฅ์ ์ผ๋ก ๋ง๋ญ๋๋ค.
- JavaScript ํฅ์: ๋๋กญ๋ค์ด ๋ฉ๋ด, ๋ชจ๋ฐ์ผ ๋ฉ๋ด ํ ๊ธ, ๋ถ๋๋ฌ์ด ์คํฌ๋กค๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ผ๋ก ๋ฉ๋ด๋ฅผ ํฅ์์ํค๊ธฐ ์ํด JavaScript๋ฅผ ์ถ๊ฐํฉ๋๋ค.
HTML (๊ธฐ๋ณธ ๋ฉ๋ด):
React (JavaScript ํฅ์ - ๋ชจ๋ฐ์ผ ๋ฉ๋ด):
import React, { useState } from 'react';
function Navigation() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const toggleMenu = () => {
setIsMenuOpen(!isMenuOpen);
};
return (
);
}
export default Navigation;
CSS (๋ชจ๋ฐ์ผ ๋ฉ๋ด ์คํ์ผ):
nav ul {
display: flex;
list-style: none;
padding: 0;
margin: 0;
}
nav ul li {
margin-right: 20px;
}
/* ๋ชจ๋ฐ์ผ ์คํ์ผ */
@media (max-width: 768px) {
nav ul {
display: none; /* ๋ชจ๋ฐ์ผ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฉ๋ด ์จ๊ธฐ๊ธฐ */
flex-direction: column;
}
nav ul.open {
display: flex; /* 'open' ํด๋์ค๊ฐ ์ถ๊ฐ๋๋ฉด ๋ฉ๋ด ํ์ */
}
}
์ ๊ทผ์ฑ์ ๋ํ ์ ๋ฐ์ ์ธ ๊ณ ๋ ค์ฌํญ
์ ์ง์ ํฅ์์ ๊ตฌํํ ๋ WCAG(์น ์ฝํ ์ธ ์ ๊ทผ์ฑ ๊ฐ์ด๋๋ผ์ธ)์ ๊ฐ์ ์ ์ธ๊ณ์ ์ธ ์ ๊ทผ์ฑ ํ์ค์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด๋ฌํ ๊ฐ์ด๋๋ผ์ธ์ ์น ์ฝํ ์ธ ๋ฅผ ์ฅ์ ๊ฐ ์๋ ์ฌ๋๋ค์ด ๋ ์ฝ๊ฒ ์ ๊ทผํ ์ ์๋๋ก ๋ง๋๋ ํ๋ ์์ํฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ช ๊ฐ์ง ์ฃผ์ ๊ณ ๋ ค์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ํค๋ณด๋ ํ์: ๋ชจ๋ ์ํธ์์ฉ ์์๊ฐ ํค๋ณด๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ทผํ๊ณ ์กฐ์ํ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ์คํฌ๋ฆฐ ๋ฆฌ๋ ํธํ์ฑ: ์๋งจํฑ HTML๊ณผ ARIA ์์ฑ์ ์ฌ์ฉํ์ฌ ์คํฌ๋ฆฐ ๋ฆฌ๋์ ์๋ฏธ ์๋ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ์์ ๋๋น: ํ ์คํธ์ ๋ฐฐ๊ฒฝ์ ์ฌ์ด์ ์ถฉ๋ถํ ์์ ๋๋น๊ฐ ์๋์ง ํ์ธํฉ๋๋ค.
- ๊ธ๊ผด ํฌ๊ธฐ: ์ฌ์ฉ์๊ฐ ์ ํธ์ ๋ฐ๋ผ ๊ธ๊ผด ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ์ ์๋๋ก ํ์ฉํฉ๋๋ค.
React ์ ์ง์ ํฅ์์ ์ด์
React์ ์ ์ง์ ํฅ์์ ๊ตฌํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ๊ฐ์ง ์ด์ ์ด ์์ต๋๋ค:
- ํฅ์๋ ์ ๊ทผ์ฑ: ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๋ฅผ ํฌํจํ์ฌ ๋ ๋์ ์ฌ์ฉ์์ธต์ด ์น์ฌ์ดํธ์ ์ ๊ทผํ ์ ์๊ฒ ํฉ๋๋ค.
- ํฅ์๋ ์ฑ๋ฅ: ์ด๊ธฐ ๋ก๋ ์๊ฐ์ ์ค์ด๊ณ ์ ๋ฐ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํฉ๋๋ค.
- ๋ ๋์ SEO: ์ฝํ ์ธ ๋ฅผ ๋ ์ฝ๊ฒ ํฌ๋กค๋งํ๊ณ ์ธ๋ฑ์ฑํ ์ ์๊ฒ ํ์ฌ ๊ฒ์ ์์ง ์์๋ฅผ ํฅ์์ํต๋๋ค.
- ์ฆ๊ฐ๋ ๋ณต์๋ ฅ: JavaScript๊ฐ ์คํจํ๊ฑฐ๋ ์ฌ์ฉํ ์ ์์ ๋๋ ์น์ฌ์ดํธ๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ๋ฏธ๋ ๋๋น: ๋ฏธ๋์ ๊ธฐ์ ๊ณผ ์ฅ์น์ ๋๋นํ์ฌ ์น์ฌ์ดํธ๋ฅผ ์ค๋น์ํต๋๋ค.
์ ์ง์ ํฅ์์ ์ํ ๋๊ตฌ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
React์์ ์ ์ง์ ํฅ์์ ๊ตฌํํ๋ ๋ฐ ๋์์ด ๋๋ ๋ช ๊ฐ์ง ๋๊ตฌ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ต๋๋ค:
- Next.js: ์๋ฒ ๋ ๋๋ง ๋ฐ ์ ์ ์์ฑ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํ ํ๋ ์์ํฌ์ ๋๋ค.
- Gatsby: React๋ก ์ ์ ์ฌ์ดํธ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ํ๋ ์์ํฌ์ ๋๋ค.
- Remix: ์น ํ์ค๊ณผ ์ ์ง์ ํฅ์์ ์ฑํํ ํ์คํ ์น ํ๋ ์์ํฌ์ ๋๋ค.
- React Helmet: React ์ปดํฌ๋ํธ์์ ๋ฌธ์ ํค๋ ํ๊ทธ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- Lighthouse: ์น์ฌ์ดํธ ์ฑ๋ฅ, ์ ๊ทผ์ฑ ๋ฐ SEO๋ฅผ ๊ฐ์ฌํ๊ธฐ ์ํ ์คํ ์์ค ๋๊ตฌ์ ๋๋ค.
๊ฒฐ๋ก
React ์ ์ง์ ํฅ์์ ์ ๊ทผ์ฑ, ์ฑ๋ฅ, ๊ฒฌ๊ณ ์ฑ์ ๊ฐ์ถ ์น์ฌ์ดํธ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ์ ๋ต์ ๋๋ค. ํต์ฌ ๊ธฐ๋ฅ๊ณผ ์ฝํ ์ธ ๊ฐ์ฉ์ฑ์ ์ฐ์ ์ํจ์ผ๋ก์จ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฅ์ด๋ JavaScript ์ฌ์ฉ ๊ฐ๋ฅ ์ฌ๋ถ์ ๊ด๊ณ์์ด ๋ชจ๋ ์ฌ๋์ด ์น์ฌ์ดํธ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ๋ณด์ฅํ ์ ์์ต๋๋ค. ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง, ์ ์ ์ฌ์ดํธ ์์ฑ, ์ฐ์ํ ์ ํ์ ๊ฐ์ ๊ธฐ์ ์ ์ฑํํจ์ผ๋ก์จ ์ฐ์ํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๊ณ ๋์์์ด ์งํํ๋ ์น ํ๊ฒฝ์์ ์ฑ๊ณตํ ์ ์๋ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ์ ๊ทผ์ฑ ์๋ ๋์์ธ๊ณผ ๊ฒฌ๊ณ ํ HTML ๊ธฐ๋ฐ์ ์ง์คํ๋ฉด ๊ธฐ๋ณธ ๊ฒฝํ์ ์ ๊ณตํ๊ณ , ๊ทธ ์์ JavaScript๊ฐ ์ํธ์์ฉ์ ํฅ์์ํจ๋ค๋ ์ ์ ๊ธฐ์ตํ์ญ์์ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉ์์ธต์ ๋ํ ๋ฟ๋ง ์๋๋ผ ์น์ฌ์ดํธ์ ์ ๋ฐ์ ์ธ ์ฑ๋ฅ๊ณผ SEO๋ฅผ ํฅ์์ํต๋๋ค. ๊ทธ๋ฌ๋ ์ ์ง์ ํฅ์์ ๋ฐ์๋ค์ด๊ณ ์ ์ธ๊ณ ๋ชจ๋ ์ฌ๋์ ์ํด ๋ ๋์ ์น ๊ฒฝํ์ ๊ตฌ์ถํ์ญ์์ค.